﻿#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/core/ocl.hpp>

using namespace cv;
using namespace std;





void parallelFunction(const cv::Range& range) {
	for (int i = range.start; i < range.end; ++i) {
		// 并行处理代码
	}
}





int main()
{
	/*
	机器学习与深度学习的应用场景
		图像分类 :使用机器学习或深度学习模型对图像进行分类。
		应用场景：医学影像分类、工业质检等。

		目标检测 :使用深度学习模型检测图像中的目标。
		应用场景：自动驾驶、安防监控等。

		语义分割 :使用深度学习模型对图像中的每个像素进行分类。
		应用场景：医学影像分析、遥感图像分析等。

		常用机器学习算法
		OpenCV 提供了以下常见的机器学习算法：

		算法	描述
		KNN	K 近邻算法，用于分类和回归。
		SVM	支持向量机，用于分类和回归。
		决策树	基于树结构的分类和回归算法。
		随机森林	基于多个决策树的集成学习算法。
		K - Means	聚类算法，用于将数据分为多个簇。
		*/


	/*
	K - Means 算法的核心思想是通过迭代优化簇中心，使得每个样本点到其所属簇中心的距离最小。
	实现步骤：
	初始化：随机选择K个样本作为初始簇中心。
	分配：将每个样本分配到距离最近的簇中心。
	更新：重新计算每个簇的中心点。
	迭代：重复步骤2和3，直到簇中心不再变化或达到最大迭代次数。
	*/

	// 生成一些随机数据
	cv::Mat data(100, 2, CV_32F);
	cv::randu(data, cv::Scalar(0, 0), cv::Scalar(100, 100));

	// 设置K值和迭代条件
	int K = 3;
	cv::Mat labels, centers;
	cv::kmeans(data, K, labels, cv::TermCriteria(cv::TermCriteria::EPS + cv::TermCriteria::MAX_ITER, 10, 1.0), 3, cv::KMEANS_PP_CENTERS, centers);

	// 输出结果
	std::cout << "Labels: " << labels << std::endl;
	std::cout << "Centers: " << centers << std::endl;







	/*
	支持向量机（SVM）是一种有监督学习算法，主要用于分类和回归任务。
	SVM 的核心思想是找到一个超平面，使得不同类别的样本点之间的间隔最大化。
	实现步骤：
	训练：通过训练数据找到一个最优超平面。
	预测：使用训练好的模型对新数据进行分类。
	*/

	// 生成一些训练数据
	cv::Mat trainData = (cv::Mat_<float>(4, 2) << 1, 1, 1, 2, 2, 1, 2, 2);
	cv::Mat labels2 = (cv::Mat_<int>(4, 1) << 1, 1, -1, -1);

	// 创建SVM模型
	cv::Ptr<cv::ml::SVM> svm = cv::ml::SVM::create();
	svm->setKernel(cv::ml::SVM::LINEAR);
	svm->setType(cv::ml::SVM::C_SVC);
	svm->setC(1);

	// 训练模型
	svm->train(trainData, cv::ml::ROW_SAMPLE, labels2);

	// 预测新数据
	cv::Mat testData = (cv::Mat_<float>(1, 2) << 1.5, 1.5);
	float response = svm->predict(testData);
	std::cout << "Predicted label: " << response << std::endl;





	/*
	主成分分析（PCA）是一种降维技术，主要用于减少数据集的维度，同时保留数据的主要特征。
	PCA通过线性变换将原始数据映射到一个新的坐标系中，使得数据在新坐标系中的方差最大化。
	实现步骤：
	计算协方差矩阵：计算数据集的协方差矩阵。
	特征值分解：对协方差矩阵进行特征值分解，得到特征向量和特征值。
	选择主成分：选择前K个最大的特征值对应的特征向量作为主成分。
	数据投影：将原始数据投影到主成分上，得到降维后的数据。
	*/
	// 生成一些数据
	cv::Mat data2 = (cv::Mat_<float>(4, 2) << 1, 2, 2, 3, 3, 4, 4, 5);

	// 创建PCA对象
	cv::PCA pca(data2, cv::Mat(), cv::PCA::DATA_AS_ROW, 1);

	// 投影数据
	cv::Mat projected = pca.project(data2);
	std::cout << "Projected data: " << projected << std::endl;







	/*
	加载预训练的深度学习模型（DNN 模块）
	OpenCV 的 DNN 模块支持加载多种深度学习框架（如TensorFlow、Caffe、PyTorch等）的预训练模型。
	通过 DNN 模块，开发者可以轻松地将深度学习模型集成到 C++ 应用程序中。
	*/
	// 加载预训练的Caffe模型
	//cv::dnn::Net net = cv::dnn::readNetFromCaffe("deploy.prototxt", "model.caffemodel");

	//// 检查模型是否加载成功
	//if (net.empty()) {
	//	std::cerr << "Failed to load model!" << std::endl;
	//	return -1;
	//}

	//std::cout << "Model loaded successfully!" << std::endl;







	////C++ OpenCV 性能优化
	////OpenCL（Open Computing Language）是一种用于编写跨平台并行程序的框架，
	////可以利用 GPU 或其他加速器来加速计算。OpenCV 支持 OpenCL 加速，可以通过以下步骤启用：
	//cv::ocl::setUseOpenCL(true); // 启用 OpenCL 加速
	//cv::UMat src, dst;
	//cv::imread("image.jpg").copyTo(src);
	//cv::GaussianBlur(src, dst, cv::Size(5, 5), 0);
	//cv::imshow("Blurred Image", dst);
	//cv::waitKey(0);


	////多线程处理是提高程序性能的另一种有效方法。OpenCV 提供了 cv::parallel_for_ 函数，可以方便地实现并行计算。
	//cv::parallel_for_(cv::Range(0, 100), parallelFunction);


	////内存拷贝是性能瓶颈之一，尤其是在处理大图像时。OpenCV 提供了 cv::Mat 的引用计数机制，可以通过引用传递图像数据，避免不必要的拷贝。
	//cv::Mat src = cv::imread("image.jpg");
	//cv::Mat dst = src.clone(); // 避免不必要的拷贝







	return 0;
}
